import tkinter as tk
from tkinter import ttk
import ipaddress

def update_info(*args):
    ip_type = ip_type_var.get()
    ip_input = ip_entry.get().strip()

    if ip_type == "IPv4":
        min_prefix, max_prefix = 1, 32
        default_ip = "192.168.1.0"
    else:
        min_prefix, max_prefix = 1, 128
        default_ip = "2001::"

    prefix_slider.config(from_=min_prefix, to=max_prefix)
    prefix_val_label.config(text=f"/{prefix_var.get()}")
    ip = ip_input if ip_input else default_ip
    prefix = prefix_var.get()

    try:
        if ip_type == "IPv4":
            net = ipaddress.IPv4Network(f"{ip}/{prefix}", strict=False)
            mask = net.netmask
            wildcard = net.hostmask   # 通配符掩码
            host_count = (net.num_addresses - 2) if prefix < 31 else net.num_addresses
            first = net.network_address + 1 if prefix < 31 else net.network_address
            last = net.broadcast_address - 1 if prefix < 31 else net.broadcast_address
            subnet_count = 2 ** (prefix - 24) if prefix >= 24 else 1
            result = [
                f"网络地址:         {net.network_address}",
                f"子网掩码:         {mask}",
                f"前缀长度:         /{prefix}",
                f"可用主机数:       {host_count}",
                f"通配符掩码:       {wildcard}",
                f"第一个可用地址:   {first}",
                f"最后一个可用地址: {last}",
                f"子网数量(C类):    {subnet_count}"
            ]
        else:
            net = ipaddress.IPv6Network(f"{ip}/{prefix}", strict=False)
            mask = net.netmask
            host_count = net.num_addresses
            first = net.network_address + 1
            last = net[-1]
            result = [
                f"网络地址:         {net.network_address}",
                f"子网掩码:         {mask}",
                f"前缀长度:         /{prefix}",
                f"可用主机数:       {host_count}",
                f"第一个可用地址:   {first}",
                f"最后一个可用地址: {last}"
            ]
    except Exception as e:
        result = [f"错误: {e}"]

    result_text.config(state=tk.NORMAL)
    result_text.delete(1.0, tk.END)
    result_text.insert(tk.END, "\n".join(result))
    result_text.config(state=tk.DISABLED)

def on_type_change():
    ip_type = ip_type_var.get()
    if ip_type == "IPv4":
        ip_entry.delete(0, tk.END)
        ip_entry.insert(0, "192.168.1.0")
        prefix_var.set(24)
    else:
        ip_entry.delete(0, tk.END)
        ip_entry.insert(0, "2001::")
        prefix_var.set(64)
    update_info()

root = tk.Tk()
root.title("IPv4/IPv6 子网掩码分配工具")

frame = ttk.Frame(root, padding=12)
frame.grid(row=0, column=0)

ip_type_var = tk.StringVar(value="IPv4")
prefix_var = tk.IntVar(value=24)

# IP类型单选框
ttk.Label(frame, text="IP类型:").grid(row=0, column=0, sticky="w")
ipv4_button = ttk.Radiobutton(frame, text="IPv4", variable=ip_type_var, value="IPv4", command=on_type_change)
ipv6_button = ttk.Radiobutton(frame, text="IPv6", variable=ip_type_var, value="IPv6", command=on_type_change)
ipv4_button.grid(row=0, column=1, sticky="w")
ipv6_button.grid(row=0, column=2, sticky="w")

# 地址输入框
ttk.Label(frame, text="地址:").grid(row=1, column=0, sticky="w")
ip_entry = ttk.Entry(frame, width=30)
ip_entry.grid(row=1, column=1, columnspan=2, sticky="we")
ip_entry.insert(0, "192.168.1.0")

# 前缀长度滑块
ttk.Label(frame, text="子网掩码长度:").grid(row=2, column=0, sticky="w")
prefix_slider = ttk.Scale(frame, from_=24, to=32, orient="horizontal", variable=prefix_var, command=lambda x: update_info())
prefix_slider.grid(row=2, column=1, sticky="we", padx=5)
prefix_val_label = ttk.Label(frame, text="/24")
prefix_val_label.grid(row=2, column=2, sticky="w")

# 结果显示框
result_text = tk.Text(frame, width=55, height=10, state=tk.DISABLED, bg="#f6f6f6", font=("Consolas", 10))
result_text.grid(row=3, column=0, columnspan=3, pady=10)

ip_type_var.trace("w", lambda *args: on_type_change())
ip_entry.bind("<KeyRelease>", lambda event: update_info())
prefix_var.trace("w", lambda *args: update_info())

update_info()

root.mainloop()